﻿module VertexFinder
    //Takes a 2D Binary Array with 1's representing tiles and 0's representing blank spaces and return an array of tuples of the coordinates of every vertex of the polygon made by the tiles
    let VertexFind (x : int [,])=
        let mutable vertex = [||]
        for i in 0 .. (x.Length)-1 do
           //Checks for any vertices in the bottom row
            if(i < x.GetLength 0 - 1) then
                if(not(x.[i,0]=x.[i+1,0])) then
                    vertex <- Array.append vertex [|(i+1,0)|]
            //Checks for any vertices in the left column
            if(i%x.GetLength 0 = 0 && i<x.Length - x.GetLength 0 - 1) then
                if(not(x.[0,i/(x.GetLength 0)]=x.[0,i/(x.GetLength 0)+1])) then
                    vertex <- Array.append vertex [|(0,i/(x.GetLength 0)+1)|]
            //Checks for any vertices in the right column           
            if(i%x.GetLength 0 = x.GetLength 0 - 1  && i<x.Length - x.GetLength 0 - 1) then
                if(not(x.[x.GetLength 0 - 1,i/(x.GetLength 0)]=x.[x.GetLength 0 - 1,i/(x.GetLength 0)+1])) then
                    vertex <- Array.append vertex [|(x.GetLength 0 ,i/(x.GetLength 0)+1)|]
            //Checks for any vertices in the top row 
            if(i > x.Length-x.GetLength 0 - 1 && i<x.Length-2) then
                if(not(x.[i%x.GetLength 0,x.Length/x.GetLength 0 - 1]=x.[i%x.GetLength 0+1,x.Length/x.GetLength 0 - 1])) then
                    vertex <- Array.append vertex [|(i%x.GetLength 0+1,x.Length/x.GetLength 0 )|]
            //Checks for any vertices in everywhere that is not an edge
            if(not(i%(x.GetLength 0) = (x.GetLength 0 - 1)) && i<x.Length - x.GetLength 0 - 1) then
                let temp1 = x.[i%(x.GetLength 0),i/(x.GetLength 0)]
                let temp2 = x.[i%(x.GetLength 0)+1,i/(x.GetLength 0)]
                let temp3 = x.[i%(x.GetLength 0),i/(x.GetLength 0)+1]
                let temp4 = x.[i%(x.GetLength 0)+1,i/(x.GetLength 0)+1]
                if(temp1 = temp2 && temp2=temp3 && not(temp3 = temp4) ||temp1 = temp2 && temp2=temp4 && not(temp4 = temp3) || temp1 = temp4 && temp4=temp3 && not(temp3 = temp2) || temp4 = temp2 && temp2=temp3 && not(temp3 = temp1)) then
                    vertex <- Array.append vertex [|(i%(x.GetLength 0)+1,i/(x.GetLength 0)+1)|]
            //Checks for vertex on the bottom left corner
            if(i =0 && x.[0,0] =1) then
                vertex <- Array.append vertex [|0,0|]
            //Checks for vertex on the bottom right corner
            if(i= x.GetLength 0 - 1 && x.[x.GetLength 0 - 1,0] =1) then
                vertex <- Array.append vertex [|x.GetLength 0 ,0|]
            //Checks for vertex on the top left corner
            if(i = x.Length-x.GetLength 0 - 1 && x.[0,x.Length/x.GetLength 0 - 1] =1) then
                vertex <- Array.append vertex [|0,x.Length/x.GetLength 0 |]
            //Checks for vertex on the top right corner
            if(i = x.Length - 1 && x.[x.GetLength 0 - 1,x.Length/x.GetLength 0 - 1] =1) then
                vertex <- Array.append vertex [|x.GetLength 0 ,x.Length/x.GetLength 0 |]
        vertex



    //Takes a 2D Binary Array with 1's representing tiles and 0's representing blank spaces and return an array of tuples of the coordinates of every concave vertex of the polygon made by the tiles
    let ConcaveVertexFind (x : int [,])=
        let mutable vertex = [||]
        for i in 0 .. x.Length - x.GetLength 0 - 1 do
          
            //Checks for any concave vertices in everywhere that is not an edge
            if(not(i%(x.GetLength 0) = (x.GetLength 0 - 1))) then
                let temp1 = x.[i%(x.GetLength 0),i/(x.GetLength 0)]
                let temp2 = x.[i%(x.GetLength 0)+1,i/(x.GetLength 0)]
                let temp3 = x.[i%(x.GetLength 0),i/(x.GetLength 0)+1]
                let temp4 = x.[i%(x.GetLength 0)+1,i/(x.GetLength 0)+1]
                if(temp1 = temp2 && temp2=temp3 && not(temp3 = temp4) && temp4=0||temp1 = temp2 && temp2=temp4 && not(temp4 = temp3) && temp3=0|| temp1 = temp4 && temp4=temp3 && not(temp3 = temp2) && temp2=0|| temp4 = temp2 && temp2=temp3 && not(temp3 = temp1) && temp1=0) then
                    vertex <- Array.append vertex [|(i%(x.GetLength 0)+1,i/(x.GetLength 0)+1)|]
        vertex 
  
    
    let ConcaveFilter (x : int [,])  (a : (int*int)[]) =
        let b = ConcaveVertexFind x
        let b1 = Array.fold (fun (a : string) b -> a + b.ToString()) "" b
        let mutable c = [||]
        for i in 0 .. a.Length-1 do
            if b1.Contains (a.[i].ToString()) then
                c <- Array.append  c [|a.[i]|]
        c
    (* 
    let y = Array2D.zeroCreate<int> 4 4
    y.[1,0] <- 1
    y.[2,0] <- 1 
    y.[3,0] <- 1
    y.[0,1] <- 1
    y.[1,1] <- 1
    y.[1,2] <- 1
    y.[1,3] <- 1
    printfn "%A" (VertexFind y)
    printfn "%A" (ConcaveFilter y  (VertexFind y))
    *)